<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>

<body>
  <div id="container"></div>
  <button id="btn-change">change</button>

  <script src="https://cdn.bootcss.com/snabbdom/0.7.3/snabbdom.js"></script>
  <script src="https://cdn.bootcss.com/snabbdom/0.7.3/snabbdom-class.js"></script>
  <script src="https://cdn.bootcss.com/snabbdom/0.7.3/snabbdom-props.js"></script>
  <script src="https://cdn.bootcss.com/snabbdom/0.7.3/snabbdom-style.js"></script>
  <script src="https://cdn.bootcss.com/snabbdom/0.7.3/snabbdom-eventlisteners.js"></script>
  <script src="https://cdn.bootcss.com/snabbdom/0.7.3/h.js"></script>
  <script type="text/javascript">
    const snabbdom = window.snabbdom
    // 定义关键函数 patch
    const patch = snabbdom.init([
      snabbdom_class,
      snabbdom_props,
      snabbdom_style,
      snabbdom_eventlisteners
    ])

    // 定义关键函数 h
    const h = snabbdom.h

    // 原始数据
    const data = [
      {
        name: '张三',
        age: '20',
        address: '北京'
      },
      {
        name: '李四',
        age: '21',
        address: '上海'
      },
      {
        name: '王五',
        age: '22',
        address: '广州'
      }
    ]
    // 把表头也放在 data 中
    data.unshift({
      name: '姓名',
      age: '年龄',
      address: '地址'
    })

    const container = document.getElementById('container')

    // 渲染函数
    let vnode
    function render(data) {
      const newVnode = h('table', {}, data.map(item => {
        const tds = [];
        for (let i in item) {
          if (item.hasOwnProperty(i)) {
            tds.push(h('td', {}, item[i] + ''))
          }
        }
        return h('tr', {}, tds);
      }))

      if (vnode) {
        // re-render
        // diff过程
        patch(vnode, newVnode)
      } else {
        // 初次渲染
        patch(container, newVnode)
      }
      vnode = newVnode;
    }

    // 初次渲染
    render(data)


    const btnChange = document.getElementById('btn-change')
    btnChange.addEventListener('click', () => {
      data[1].name = "码路";
      data[2].age = "30";
      // re-render
      render(data)
    })

  </script>
</body>

</html>